﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GalaSoft.MvvmLight;
using System.Collections.ObjectModel;
using SystemScanningGui.ScanService;
using System.Data.Services.Client;
using System.Windows;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;
using System.ServiceModel.DomainServices.Client;

namespace SystemScanningGui.ViewModels
{
	class CompareTwoComputersViewModel : ViewModelBase
	{
		#region Fields

		private Computer _ComputerSelectionLeft;
		private Computer _ComputerSelectionRight;
		private DataServiceCollection<Computer> _computersLeft = new DataServiceCollection<Computer>();
		private DataServiceCollection<Computer> _computersRight = new DataServiceCollection<Computer>();
		private CoreEntities _entities = null;// SystemScanningGui.App.Current.Host.Source
		//new CoreEntities(new Uri("./Services/SystemScanService.svc"));
		private DataServiceCollection<Scan> _leftScans = new DataServiceCollection<Scan>();
		private RelayCommand _LoadComparisonCommand = null;
		private DataServiceCollection<Scan> _rightScans = new DataServiceCollection<Scan>();
		private ViewModels.ScanComparisonViewModel _scanComparisonViewModel = new ViewModels.ScanComparisonViewModel();
		private Scan _ScanSelectionLeft;
		private Scan _ScanSelectionRight;

		#endregion Fields

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the CompareTwoComputersViewModel class.
		/// </summary>
		public CompareTwoComputersViewModel()
		{
			// This is a crappy hack that I hate... but it's pretty dynamic and may not totally suck. I couldn't find a more "correct" way.
			var tard = SystemScanningGui.App.Current.Host.Source;
			var withoutTheClientBin = tard.AbsoluteUri.Substring(0, tard.AbsoluteUri.IndexOf("ClientBin/"));
			Uri uri = new Uri(withoutTheClientBin + "Services/SystemScanService.svc");
			_entities = new CoreEntities(uri);
			
			// this could probably be a single list rather than two.
			this.LoadComputers(_computersLeft, "Left");
			this.LoadComputers(_computersRight, "Right");
		}

		#endregion Constructors

		#region Properties

		public Computer ComputerSelectionLeft
		{
			get { return _ComputerSelectionLeft; }
			set
			{
				if (value != _ComputerSelectionLeft)
				{
					_ComputerSelectionLeft = value;
					LoadScansAndSendPropertyChangeNotifications(value, _leftScans, "Left");
				}
			}
		}

		public Computer ComputerSelectionRight
		{
			get { return _ComputerSelectionRight; }
			set
			{
				if (value != _ComputerSelectionRight)
				{
					_ComputerSelectionRight = value;
					LoadScansAndSendPropertyChangeNotifications(value, _rightScans, "Right");
				}
			}
		}

		public DataServiceCollection<Computer> ComputersLeft
		{
			get { return _computersLeft; }
			private set
			{
				_computersLeft = value;
			}
		}

		public DataServiceCollection<Computer> ComputersRight
		{
			get { return _computersRight; }
			private set
			{
				_computersRight = value;
			}
		}

		public DataServiceCollection<Scan> LeftScans
		{
			get
			{
				return _leftScans;
			}
		}

		public RelayCommand LoadComparisonCommand
		{
			get
			{
				if (_LoadComparisonCommand == null)
				{
					_LoadComparisonCommand = new RelayCommand(
						() => // exec action
						{
							_scanComparisonViewModel.Initialize(ScanSelectionLeft,
								ScanSelectionRight,
								this.ComputerSelectionLeft,
								this.ComputerSelectionRight,
								_entities);
						},
						() => // canexecute
						{
							return ScanSelectionLeft != null && ScanSelectionRight != null;
						}
						);
				}
				return _LoadComparisonCommand;
			}
			set { _LoadComparisonCommand = value; }
		}

		public DataServiceCollection<Scan> RightScans
		{
			get
			{
				return _rightScans;
			}
		}

		public ViewModels.ScanComparisonViewModel ScanComparison
		{
			get
			{
				return _scanComparisonViewModel;
			}
		}

		public Scan ScanSelectionLeft
		{
			get { return _ScanSelectionLeft; }
			set
			{
				if (_ScanSelectionLeft != value)
				{
					_ScanSelectionLeft = value;
					this.RaisePropertyChanged("ScanSelectionLeft");
					this.LoadComparisonCommand.RaiseCanExecuteChanged();
				}
			}
		}

		public Scan ScanSelectionRight
		{
			get { return _ScanSelectionRight; }
			set
			{
				if (_ScanSelectionRight != value)
				{
					_ScanSelectionRight = value;
					this.RaisePropertyChanged("ScanSelectionRight");
					this.LoadComparisonCommand.RaiseCanExecuteChanged();
				}
			}
		}

		#endregion Properties

		#region Methods

		// Private Methods 



		private void LoadScansAndSendPropertyChangeNotifications(Computer c, DataServiceCollection<Scan> scans, string side)
		{
			if (c == null)
			{
				scans.Clear();
				return;
			}

			var q =
				from s in _entities.Scans
				where s.ComputerID == c.ComputerID
				orderby s.Performed descending
				select s;


			//var dsq = q as DataServiceQuery<Scan>;
			scans.Clear();
			scans.LoadAsync(q);
		}



		private void LoadComputers(DataServiceCollection<Computer> ocComputer, string side)
		{
			var q =
				from c in _entities.Computers
				select c;
			ocComputer.Clear();
			ocComputer.LoadAsync(q);// as DataServiceQuery<Computer>);
		}

		#endregion Methods
	}
}
